package com.sesxh.project.knowledge.biz.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.sesxh.frame.core.exceptions.ServiceLogicalException;
import com.sesxh.frame.core.util.ZAlert;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.elasticsearch.action.DocWriteResponse.Result;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.common.Strings;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.sesxh.project.knowledge.biz.util.ElasticUtil;
import com.sesxh.project.knowledge.biz.dto.ESContent;
import com.sesxh.project.knowledge.biz.dto.SearchDto;
import com.sesxh.project.knowledge.biz.enums.ElasticTypes;
import com.sesxh.project.knowledge.biz.esservice.ElasticTransportService;
@Service
public class KnowledgeSearchService {
	

	@Autowired
	ElasticTransportService elasticService;
	
	
    @Value("${elastic.index-name}")
    private String indexName;
    
	public List<Long> searchContentIds(SearchDto searchDto) {
		
		String keywords = searchDto.getKeywords();
		
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.fetchSource(new FetchSourceContext(true, new String[]{"id"}, Strings.EMPTY_ARRAY));
	
		
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
			.should(QueryBuilders.matchPhraseQuery("title", keywords))
			.should(QueryBuilders.matchPhraseQuery("content", keywords))
			.should(QueryBuilders.matchPhraseQuery("perName", keywords));
		//.should(QueryBuilders.matchPhraseQuery("keywords", keywords)).minimumShouldMatch(1);
		
		//SortBuilder<?> fieldSortBuilder = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);
		
		
		int pageNo = searchDto.getPageNo() == null ? 1 : searchDto.getPageNo();
		int pageSize = searchDto.getPageSize() == null ? 10 : searchDto.getPageSize();
		
		int from = (pageNo - 1) * pageSize;
		SearchResponse searchResponse = elasticService.getClient().prepareSearch(indexName).setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setSource(searchSourceBuilder)
				.setQuery(boolQueryBuilder)
				//.addSort(fieldSortBuilder)
				.setFrom(from)
				.setSize(pageSize)
				.execute()
				.actionGet();
		SearchHits hits = searchResponse.getHits();
		
		if (hits == null || hits.getTotalHits().value <= 0) {
			return Lists.newArrayList();
		}
		
		
		List<Long> dataList = Lists.newArrayList();
		for (SearchHit hit : hits) {
			Map<String, Object> dataEL = hit.getSourceAsMap();
			Long id = Long.valueOf("" + dataEL.get("id"));
			dataList.add(id);
		}
		return dataList;
	}
	
	
	public void createContent( ESContent esContent) {
		try {
			if (esContent.getCreateTime() != null) {
				SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date date = dFormat.parse(dFormat.format(esContent.getCreateTime()));
				esContent.setCreateTime(date);
			}
			if (esContent.getUpdateTime() != null) {
				SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date date = dFormat.parse(dFormat.format(esContent.getUpdateTime()));
				esContent.setUpdateTime(date);
			}
			String _id =  "_" + esContent.getId();
			IndexResponse indexResponse = elasticService.indexDocument(String.valueOf(_id),ElasticUtil.toDocument(esContent));
			Result res = indexResponse.getResult();
			if (!(res.getLowercase().equals("created") || res.getLowercase().equals("updated"))) {
				throw new ServiceLogicalException("新增失败：" + indexResponse.getResult().toString());
			}

		} catch (Exception e) {
			ZAlert.throwSLE("同步苏索引擎发生异常"+e.getMessage());
		}
	}
	
	
	public void updateContent(@RequestBody ESContent esContent) {
		try {
			String _id = "_" + esContent.getId();

			UpdateResponse updateResponse = elasticService.updateDocument(String.valueOf(_id),ElasticUtil.toDocument(esContent));
			if (!updateResponse.getResult().equals(Result.UPDATED)) {
				throw new ServiceLogicalException("更新失败：" + updateResponse.getResult().toString());
			}
		} catch (Exception e) {
			ZAlert.throwSLE("同步苏索引擎发生异常"+e.getMessage());
		}
	}

	
	public void deleteContent(Long id) {
		try {
			String _id = "_" + id;
			DeleteResponse resp =	elasticService.deleteDocument( _id);
			if (!resp.getResult().equals(Result.DELETED)) {
				throw new ServiceLogicalException("删除失败：" + resp.getResult().toString());
			}
		} catch (Exception e) {
			ZAlert.throwSLE("同步苏索引擎发生异常"+e.getMessage());
		}
	}
	
}